import { CSSProperties, defineComponent, getCurrentInstance, PropType, ref, watchEffect, unref } from 'vue'
import { findDOMNode } from '../_util/props-util'
import useResizeObserver from '../_util/hooks/useResizeObserver'
import BorderLight from '../border-light'
import { TabbarType } from './Tabs'
import { TabPaneProps } from './TabPane'
import { MaybeRef } from '@vueuse/core'
import { TabsContextProps } from './interface'

const preCls = 'x-tabs'

export type Tab = Array<TabPaneProps | string | number>

export default defineComponent({
  name: preCls,
  props: {
    value: [String, Number, Object] as PropType<MaybeRef<string | number | undefined>>,
    type: String as PropType<TabbarType>,
    tabs: Object as PropType<TabsContextProps['tabpanes']>
  },
  directives: {
    [BorderLight.name]: BorderLight
  },
  emits: ['change'],
  setup(props, { emit }) {
    const { proxy: vm } = getCurrentInstance()!

    function getActiveRef() {
      return vm!.$refs[`tab_${unref(props.value)}`] as HTMLElement
    }

    function updateBarStyle(tabEl: HTMLElement) {
      if (!tabEl) return
      const container = findDOMNode(vm),
        scrollLeft = container?.scrollLeft,
        rect = container?.getBoundingClientRect(),
        rect2 = tabEl?.getBoundingClientRect()

      barStyleRef.value = {
        left: (rect2?.left - rect.left + scrollLeft || 0) + 'px',
        width: Math.round(rect2?.width || 0) + 'px'
      }
    }

    useResizeObserver(() => {
      updateBarStyle(getActiveRef())
    })

    const barStyleRef = ref<CSSProperties>()
    watchEffect(() => {
      void props.tabs
      void props.type
      updateBarStyle(getActiveRef())
    })

    function onClick(key: string | number) {
      emit('change', key)
    }

    function items() {
      return props.tabs!.value.map((tab, i) => {
        const key = tab.name ?? tab.label ?? i
        const isActive = key == unref(props.value)
        let node = (
          <div role='tab' aria-selected={isActive} tabindex={i} class={`${preCls}_tab ${preCls}_tab-${isActive ? 'active' : 'inactive'}`} key={key} ref={`tab_${key}`} onClick={() => onClick(key)} v-border-light={{ borderWidth: 1, style: { opacity: 0.2 } }}>
            {tab.$slots.label?.() ?? tab.label ?? key}
          </div>
        )
        return node
      })
    }

    return () => {
      return (
        <div role='tablist' class={`${preCls}_nav ${preCls}_nav-${props.type}`}>
          {items()}
          <div class={`${preCls}_bar`} style={barStyleRef.value} />
        </div>
      )
    }
  }
})
